<template>
    <div class="editorComponent" :class="{ 'editorContainerDocument': props.documentModel }" :style="props.fontSize && props.fontSize > 0 ? `font-size: ${props.fontSize}px;` : ''">
        <Toolbar
            class="toolbarComponent" :class="{ 'toolbarComponentShadow': !props.noToolShadow }"
            :editor="editorRef"
            :defaultConfig="_toolbarConfig"
            :mode="'default'"
        />
        <div class="editorContainer">
            <div class="editorContainerWrapper">
                <div class="titleContainer" v-if="props.documentModel">
                    <input type="text" 
        :value="props.title" 
        @input="updateTitle(($event.target as HTMLInputElement).value)" :placeholder="props.titlePlaceholder">
                </div>
                <div class="editorContainerContent" @click="Focus()">
                    <Editor class="wangEditorContent"
                        :style="'height: auto;'"
                        v-model="editorValue"
                        :defaultConfig="editorConfig"
                        :mode="'default'"
                        @onCreated="handleCreated"
                        @onChange="handleChange"
                        @onFocus="handleFocus"
                        @onBlur="handleBlur"
                        @customPaste="customPaste"
                        @onDestroyed="handleDestroyed"
                        @onMaxLength="handleMaxLength"
                    />
                </div>
            </div>
        </div>
    </div>
</template>
<script lang="ts">
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { defineComponent, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { IDomEditor, IEditorConfig } from '@wangeditor/editor';
import { FileProcessing } from "@util/file_processing";

export default defineComponent({
    name: 'editorComponent',
});
</script>

<script setup lang="ts">
    // 编辑器实例，必须用 shallowRef
    const editorRef = shallowRef();

    // 插入图片或视频函数类型
    type InsertFnType = {
        (url: string, alt: string, href: string): void;
        (url: string, poster: string): void;
    };

    // 获取 props 参数
    const props = withDefaults(defineProps<{
        modelValue?: string;         // 内容
        placeholder?: string;   // 占位符文本
        readOnly?: boolean;     // 是否只读
        autoFocus?: boolean;    // 是否自动聚焦
        maxLength?: number;     // 最大字符数
        documentModel?: boolean;     // 是否是文档编辑
        title?: string;        // 标题
        titlePlaceholder?: string;   // 标题占位符
        toolbarConfig?: string[]; // 工具栏配置
        noToolShadow?: boolean; // 是否去除工具栏阴影
        fontSize?: number;      // 字号
        customPaste?: (event: ClipboardEvent, editor: IDomEditor) => boolean; // 自定义粘贴处理函数
        uploadImage?: (file: File, insertFn: InsertFnType) => void; // 自定义上传图片
        uploadVideo?: (file: File, insertFn: InsertFnType) => void; // 自定义上传视频
    }>(), {
        modelValue: '',
        placeholder: '',
        readOnly: false,
        autoFocus: true,
        maxLength: 0,
        documentModel: false,
        title: '',
        titlePlaceholder: ''
    });
    
    // 内容
    const editorValue = ref(props.modelValue);

    // 清空内容
    const clear = () => {
        Focus(); // 重新聚焦编辑器
        editorRef.value.clear(); // 清空编辑器
    }

    // 定义事件
    const emit = defineEmits<{
        (e: 'update:modelValue', newValue: string): void;   // 更新 v-model 值
        (e: 'update:title', value: string): void;           // 更新 v-model 值
        (e: 'onConfig', editor: IDomEditor): void;          // 配置完毕
        (e: 'onChange', editor: IDomEditor): void;          // 内容变化
        (e: 'onFocus', editor: IDomEditor): void;           // 获取焦点
        (e: 'onBlur', editor: IDomEditor): void;            // 失去焦点
        (e: 'onMaxLength', editor: IDomEditor): void;       // 超过最大长度
        (e: 'onDestroyed', editor: IDomEditor): void;       // 销毁编辑器
    }>();

    // 自定义工具栏配置，排除全屏按钮
    const _toolbarConfig = {
        excludeKeys: ['fullScreen'], // 排除全屏按钮

    }

    onMounted(() => {
        if (props.toolbarConfig) {
            (_toolbarConfig as any).toolbarKeys = props.toolbarConfig; // 动态扩展属性
        }
    });

    // 编辑器配置
    const editorConfig: Partial<IEditorConfig> = {
        MENU_CONF: { },
        placeholder: props.placeholder,
        readOnly: props.readOnly,
        maxLength: props.maxLength,
        autoFocus: props.autoFocus,
        scroll: false,
    };
    
    // 配置上传图片
    editorConfig.MENU_CONF['uploadImage'] = {
        server: '',
        async customUpload(file: File, insertFn: InsertFnType) {
            if(props.uploadImage) props.uploadImage(file, insertFn);
            else
            {
                const base64 = await FileProcessing.fileToBase64(file as File) as string;
                // 最后插入图片
                insertFn(base64, "图片", "");
            }
        }
    }

    // 配置上传视频
    editorConfig.MENU_CONF['uploadVideo'] = {
        server: '',
        async customUpload(file: File, insertFn: InsertFnType) {
            if(props.uploadVideo) props.uploadVideo(file, insertFn);
            else
            {
                // 读取文件为 base64
                const base64 = await FileProcessing.fileToBase64(file as File) as string;
                // 获取视频封面
                const poster = await FileProcessing.getVideoPoster(file as File) as string;
                // 最后插入视频
                insertFn(base64, poster);
            }
        }
    }

    // 编辑器创建完成
    const handleCreated = (editor) => {
        editorRef.value = editor // 记录 editor 实例，重要
        emit('onConfig', editor);
    }
    // 内容变化
    const handleChange = (editor) => {
        emit('update:modelValue', editorRef.value.getHtml()); // 更新编辑器内容
        emit('onChange', editor);
    }
    // 当需要修改 modelValueTitle 时调用
    function updateTitle(newTitle: string) {
        emit('update:title', newTitle);
    }
    // 得到焦点
    const handleFocus = (editor) => { 
        console.log('得到焦点');
        emit('onFocus', editor);
    }
    // 失去焦点
    const handleBlur = (editor) => { 
        console.log('失去焦点');
        emit('onBlur', editor);
    }
    // 自定义粘贴
    const customPaste = (editor, event, callback) => {
        if (props.customPaste) {
            let prevent = props.customPaste(event, editor);
            callback(prevent);
        }
    }
    // 超过最大长度
    const handleMaxLength = (editor) => {
        emit('onMaxLength', editor);
    }
    // 销毁编辑器
    const handleDestroyed = (editor) => {
        emit('onDestroyed', editor);
    }
    
    // 监听 props 变化并更新编辑器配置
    watch(() => props.modelValue, (newvValue) => {
        if (editorRef.value) {
            editorValue.value = newvValue;
        }
    });

    // 组件销毁时，也及时销毁编辑器
    onBeforeUnmount(() => {
        const editor = editorRef.value
        if (editor == null) return
        editor.destroy()
    });

    // 获取焦点
    const Focus = () => {
        if (editorRef.value) editorRef.value.focus();
    };
    // 失去焦点
    const Blur = () => {
        if (editorRef.value) editorRef.value.blur();
    };

    // 获取编辑器内容的纯文本
    const getText = () => {
        if (editorRef.value) {
            return editorRef.value.getText(); // 获取纯文本
        }
        return ''; // 如果编辑器未创建，返回空字符串
    };

    // 向父组件公开方法
    defineExpose({
        Focus,
        Blur,
        getText,
        clear
    });

</script>

<style scoped>
.editorComponent {
    width: 100%;
    position: relative;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

/* 头部 */
.editorComponent .toolbarComponent {
    width: 100%;
    padding: 0 auto;
    position: relative;
}
.editorComponent .toolbarComponent.toolbarComponentShadow::after {
    content: '';
    display: block;
    width: 100%;
    position: absolute;
    bottom: -5px;
    height: 5px;
    /* 上下渐变 */
    background: linear-gradient(to bottom, rgba(0, 0, 0, .1) 0%, transparent 100%);
}

/* 内容区域 */
.editorComponent .editorContainer {
    width: 100%;
    height: 100%;
    position: relative;
    overflow: hidden;
    overflow-y: auto;
}

/* 文档标题 */
.editorComponent .editorContainer .titleContainer {
    width: 100%;
    padding: 20px 0;
    height: 75px;
    border-bottom: 1px solid #e8e8e8;
}
.editorComponent .editorContainer .titleContainer input {
    font-size: 30px;
    border: 0;
    outline: none;
    width: 100%;
    line-height: 1;
    background-color: rgba(245, 245, 245, 0);
}


/* 文本编辑框 */
.editorComponent .editorContainer .editorContainerWrapper {
    width: 100%;
    min-height: 100%;
    position: relative;
    display: flex;
    flex-direction: column;
    
}
.editorComponent .editorContainer .editorContainerWrapper .editorContainerContent {
    width: 100%;
    height: 100%;
    flex-grow: 1; /* 占满父容器的剩余高度 */
    /* 将鼠标指针换成文字编辑 */
    cursor: text;
}
.editorComponent .editorContainer .editorContainerWrapper .editorContainerContent .wangEditorContent {
    width: 100%;
}

/* 文档模式 */
.editorContainerDocument .editorContainer {
    padding: 30px 10%;

}
.editorContainerDocument .editorContainer .editorContainerWrapper {
    width: 100%;
    min-height: 100%;
    background-color: rgba(255, 255, 255, 1);
    border-radius: 10px;
    box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.1);
    padding: 20px 50px 50px 50px;

}
.editorContainerDocument .editorContainer .editorContainerWrapper .editorContainerContent {
    min-height: calc(100% - 75px);
}
.editorContainerDocument .toolbarComponent {
    background-color: rgba(255, 255, 255, 1);
    display: flex;
    justify-content: center;
    align-items: center;
}
</style>

<style>
/* 控制编辑器中的视频尺寸 */
.editorComponent .wangEditorContent .w-e-textarea-video-container video {
    max-width: 100%;   /* 设置最大宽度为容器的100% */
    height: auto;      /* 高度自动适应 */
}

.editorComponent .toolbarComponent .w-e-toolbar, .editorComponent .wangEditorContent .w-e-text-container {
    background-color: transparent;
}

/* 1. 强制向上弹出 + 限制高度 */
.w-e-drop-panel {
  bottom: 100% !important;
  top: auto !important;
  max-height: 200px;
  overflow-y: auto;
}
</style>